% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
% ex: ts=4 sw=4 ft=erlang et
% Licensed under the Apache License, Version 2.0 (the "License"); you may not
% use this file except in compliance with the License. You may obtain a copy of
% the License at
%
%   http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
% License for the specific language governing permissions and limitations under
% the License.

% Windows is "special" so we treat it "specially"
Msys = "msys2_shell.cmd -defterm -no-start -ucrt64 -here -lc ".

PreHooks = [
    {"(linux|darwin)", compile, "make CONFIG_LTO=y -C quickjs -j8 libquickjs.lto.a qjsc"},
    {"freebsd", compile, "gmake -C quickjs -j8 libquickjs.a qjsc"},
    {"win32", compile, Msys ++ "'make -C quickjs qjsc'"},
    {"(linux|darwin|freebsd|win32)", compile, "escript build_js.escript compile"}
].

PostHooks = [
    {"(linux|darwin)", clean, "make -C quickjs clean"},
    {"freebsd", clean, "gmake -C quickjs clean"},
    {"win32", clean, Msys ++ "'make -C quickjs clean'"},
    {"(linux|darwin|freebsd|win32)", clean, "escript build_js.escript clean"}
].

% We're not building a driver just an executable so we don't
% need all the Erlang/OTP headers and libraries
ResetFlags = [
    {"ERL_CFLAGS", ""},
    {"ERL_LDFLAGS", ""},
    {"EXE_CFLAGS", ""},
    {"EXE_LDFLAGS", ""}
].

LinuxDarwinEnv = [
    {"CFLAGS", "$CFLAGS -flto -g -Wall -DCONFIG_LTO=y -O2 -Iquickjs"},
    {"LDFLAGS", "$LDFLAGS -flto -lm quickjs/libquickjs.lto.a"}
] ++ ResetFlags.

FreeBSDEnv  = [
    {"CFLAGS", "$CFLAGS -g -Wall -O2 -Iquickjs"},
    {"LDFLAGS", "$LDFLAGS -lm -lpthread quickjs/libquickjs.a"}
] ++ ResetFlags.

WindowsEnv = [
    {"CFLAGS", "-D_GNU_SOURCE -DCONFIG_BIGNUM -O2 -fwrapv -DCONFIG_VERSION=\\\"0\\\" -Iquickjs"},
    {"EXE_CC_TEMPLATE", "gcc.exe -g -c $CFLAGS $PORT_IN_FILES -o $PORT_OUT_FILE"},
    {"EXE_LINK_TEMPLATE", "gcc.exe -g -lm $PORT_IN_FILES $LDFLAGS -o $PORT_OUT_FILE"}
].

% couchjs_*_bytecode.c sources are auto-generated by build_js.escript
%
UnixMainjsSrc = ["c_src/couchjs.c", "c_src/couchjs_mainjs_bytecode.c"],
UnixCoffeeSrc = ["c_src/couchjs.c", "c_src/couchjs_coffee_bytecode.c"],

WindowsBaseSrc = [
    "quickjs/quickjs.c",
    "quickjs/libregexp.c",
    "quickjs/libunicode.c",
    "quickjs/cutils.c",
    "quickjs/libbf.c"
].

WindowsMainjsSrc = WindowsBaseSrc ++ UnixMainjsSrc.
WindowsCoffeeSrc = WindowsBaseSrc ++ UnixCoffeeSrc.

PortSpecs = [
    {"(linux|darwin)", "priv/couchjs_mainjs", UnixMainjsSrc, [{env, LinuxDarwinEnv}]},
    {"(linux|darwin)", "priv/couchjs_coffee", UnixCoffeeSrc, [{env, LinuxDarwinEnv}]},
    {"freebsd", "priv/couchjs_mainjs", UnixMainjsSrc, [{env, FreeBSDEnv}]},
    {"freebsd", "priv/couchjs_coffee", UnixCoffeeSrc, [{env, FreeBSDEnv}]},
    {"win32", "priv/couchjs_mainjs.exe", WindowsMainjsSrc, [{env, WindowsEnv}]},
    {"win32", "priv/couchjs_coffee.exe", WindowsCoffeeSrc, [{env, WindowsEnv}]}
].

AddConfig = [
    {port_specs, PortSpecs},
    {pre_hooks, PreHooks},
    {post_hooks, PostHooks}
].

lists:foldl(fun({K, V}, CfgAcc) ->
    case lists:keyfind(K, 1, CfgAcc) of
        {K, Existent} when is_list(Existent) andalso is_list(V) ->
            lists:keystore(K, 1, CfgAcc, {K, Existent ++ V});
        false ->
            lists:keystore(K, 1, CfgAcc, {K, V})
    end
end, CONFIG, AddConfig).
